package com.example.wuyeguanli.tools;

import com.example.wuyeguanli.entiy.Complaint;
import com.example.wuyeguanli.entiy.Facility;
import com.example.wuyeguanli.entiy.FacilityRental;
import com.example.wuyeguanli.entiy.Owner;
import com.example.wuyeguanli.entiy.Register;
import com.example.wuyeguanli.entiy.Repair;
import com.example.wuyeguanli.entiy.Response;
import com.example.wuyeguanli.entiy.Room;
import com.example.wuyeguanli.entiy.VisitInfo;
// import com.example.wuyeguanli.entiy.Fee; // 废弃: Fee实体不再使用，由Room实体替代
// import com.example.wuyeguanli.entiy.Visitor; // 废弃: Visitor实体已合并到VisitInfo

import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.PUT; // 重构: 引入PUT方法
import retrofit2.http.Part;
import retrofit2.http.Path;
import retrofit2.http.Query;

public class ApiClient {
    public static String BASE_URL =  "http://121.40.29.195:8080";
    private static ApiService apiService;
    private static final String CHAR_LOWER = "abcdefghijklmnopqrstuvwxyz";
    private static final String CHAR_UPPER = CHAR_LOWER.toUpperCase();
    private static final String NUMBER = "0123456789";
    private static final String DATA_FOR_RANDOM_STRING = CHAR_LOWER + CHAR_UPPER + NUMBER;
    private static final SecureRandom random = new SecureRandom();

    // 我们需要一个方法来重新构建Retrofit实例，以便URL的修改能生效
    private static Retrofit retrofitInstance;

    static {
        // 初始构建
        buildRetrofit();
    }

    // 动态构建或重新构建Retrofit的方法
    private static void buildRetrofit() {
        retrofitInstance = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        apiService = retrofitInstance.create(ApiService.class);
    }

    /**
     * 新增方法: 仅用于测试，用于修改服务器地址。
     * @param newUrl 新的服务器基础URL
     */
    public static void setBaseUrlForTesting(String newUrl) {
        BASE_URL = newUrl;
        // 重新构建Retrofit，让新URL生效
        buildRetrofit();
    }

    interface ApiService {
        // 重构: API路径、方法和参数已根据后端重构进行全面更新

        // 注册
        @POST("/users/register")
        Call<Response<Object>> register(@Body Register register);

        // 登录
        @POST("/users/login")
        Call<Response<Object>> login(@Body Owner owner);

        // 查找账号
        @GET("/users/{phone}")
        Call<Response<Owner>> findUser(@Path("phone") String phone);

        // 新建报修
        @POST("/repairs/add")
        Call<Response<Object>> addRepair(@Body Repair repair);

        // 查看房间全部报修
        @GET("/repairs/room/{roomNumber}")
        Call<Response<List<Repair>>> getRepairByRoomNumber(@Path("roomNumber") String roomNumber);

        // 确认已处理报修
        @PUT("/repairs/finish/{workOrderId}")
        Call<Response<Object>> finishRepair(@Path("workOrderId") String workOrderId);

        // 查询房间余额
        @GET("/fees/room/{roomNumber}")
        Call<Response<Room>> getRoomBalances(@Path("roomNumber") String roomNumber);

        // 新增投诉
        @POST("/complaints/add")
        Call<Response<Object>> submitComplaint(@Body Complaint complaint);

        // 新增: 根据业主手机号获取投诉列表
        @GET("/complaints/owner/{ownerPhone}")
        Call<Response<List<Complaint>>> getComplaintsByOwner(@Path("ownerPhone") String ownerPhone);

        // 废弃: Visitor相关接口已移除
        // @POST("/visitor/add")
        // Call<Response<Object>> addVisitor(@Body Visitor visitor);
        // @GET("/visitor/{roomNumber}")
        // Call<Response<List<Visitor>>> getVisitorByRoomNumber(@Path("roomNumber") String roomNumber);

        // 新增访客信息
        @POST("/visit-infos/add")
        Call<Response<Object>> addVisitInfo(@Body VisitInfo visitInfo);

        // 查询访客信息
        @GET("/visit-infos/room/{roomNumber}")
        Call<Response<List<VisitInfo>>> getVisitInfoByRoomNumber(@Path("roomNumber") String roomNumber);

        // 查询设施
        @GET("/facilities")
        Call<Response<List<Facility>>> getFacilities();

        // 新增预定
        @POST("/facility-rentals/add")
        Call<Response<Object>> addFacilityRental(@Body FacilityRental facilityRental);

        // 1. 新增: 生成工单号接口
        @GET("/api/work-orders/generate")
        Call<Response<String>> generateWorkOrder(@Query("type") String type);

        // 2. 恢复: 单独上传图片的接口
        @Multipart
        @POST("/images/upload")
        Call<Response<Object>> uploadImage(@Part MultipartBody.Part imageFile, @Part("filename") RequestBody filename);
    }

    public interface OnCompleteListener<T> {
        void onSuccess(T data);
        void OnError(Throwable error);
    }

    private class ApiCallback<T> implements Callback<T> {
        private final OnCompleteListener<T> listener;

        private ApiCallback(OnCompleteListener<T> listener) {
            this.listener = listener;
        }

        @Override
        public void onResponse(Call<T> call, retrofit2.Response<T> response) {
            if (response.isSuccessful() && response.body() != null) {
                listener.onSuccess(response.body());
            } else {
                try {
                    String errorMsg = response.errorBody() != null ? response.errorBody().string() : "Unknown server error";
                    listener.OnError(new IOException(errorMsg));
                } catch (IOException e) {
                    listener.OnError(e);
                }
            }
            EspressoIdlingResource.decrement(); // 请求结束，计数器减1
        }

        @Override
        public void onFailure(Call<T> call, Throwable t) {
            listener.OnError(t);
            EspressoIdlingResource.decrement(); // 请求结束，计数器减1
        }
    }

    // 注册
    public void register(Register register, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<Object>> call = apiService.register(register);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 登录
    public void login(String phone, String password, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        // 重构: 登录改用POST，需要创建一个Owner对象作为请求体
        Owner owner = new Owner(phone, password, null); // username在登录时不需要
        Call<Response<Object>> call = apiService.login(owner);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 查找账号
    public void findUser(String phone, final OnCompleteListener<Response<Owner>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<Owner>> call = apiService.findUser(phone);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 新建报修
    public void addRepair(Repair repair, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<Object>> call = apiService.addRepair(repair);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 查看房间全部报修
    public void getRepairByRoomNumber(String roomNumber, final OnCompleteListener<Response<List<Repair>>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<List<Repair>>> call = apiService.getRepairByRoomNumber(roomNumber);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 确认已处理报修
    public void finishRepair(String workOrderId, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<Object>> call = apiService.finishRepair(workOrderId);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 查询房间余额
    public void getRoomBalances(String roomNumber, final OnCompleteListener<Response<Room>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        // 重构: 响应类型从Fee改为Room
        Call<Response<Room>> call = apiService.getRoomBalances(roomNumber);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 新增投诉
    public void submitComplaint(Complaint complaint, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<Object>> call = apiService.submitComplaint(complaint);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 新增: 调用获取投诉列表的方法
    public void getComplaintsByOwner(String ownerPhone, final OnCompleteListener<Response<List<Complaint>>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<List<Complaint>>> call = apiService.getComplaintsByOwner(ownerPhone);
        call.enqueue(new ApiCallback<>(listener));
    }

    // 废弃: Visitor相关方法已移除
    // public void addVisitor(...)
    // public void getVisitorByRoomNumber(...)

    // 新增访客信息
    public void addVisitInfo(VisitInfo visitInfo, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<Object>> call = apiService.addVisitInfo(visitInfo);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 查询访客信息
    public void getVisitInfoByRoomNumber(String roomNumber, final OnCompleteListener<Response<List<VisitInfo>>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<List<VisitInfo>>> call = apiService.getVisitInfoByRoomNumber(roomNumber);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 查询设施
    public void getFacilities(final OnCompleteListener<Response<List<Facility>>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<List<Facility>>> call = apiService.getFacilities();
        call.enqueue(new ApiCallback<>(listener));
    }
    // 新增预定
    public void addFacilityRental(FacilityRental facilityRental, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<Object>> call = apiService.addFacilityRental(facilityRental);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 1. 新增: 调用生成工单号的方法
    public void generateWorkOrder(String type, final OnCompleteListener<Response<String>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        Call<Response<String>> call = apiService.generateWorkOrder(type);
        call.enqueue(new ApiCallback<>(listener));
    }
    // 2. 恢复: 调用上传图片的方法
    public void uploadImage(File imageFile, String newFilename, final OnCompleteListener<Response<Object>> listener) {
        EspressoIdlingResource.increment(); // 请求开始，计数器加1
        RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), imageFile);
        MultipartBody.Part imageBody = MultipartBody.Part.createFormData("image", newFilename, requestFile);
        RequestBody filenameBody = RequestBody.create(MediaType.parse("text/plain"), newFilename);
        Call<Response<Object>> call = apiService.uploadImage(imageBody, filenameBody);
        call.enqueue(new ApiCallback<>(listener));
    }

    // 生成随机ID
    public static String getRandomId(int length) {
        if (length < 1) throw new IllegalArgumentException();
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            int rndCharAt = random.nextInt(DATA_FOR_RANDOM_STRING.length());
            char rndChar = DATA_FOR_RANDOM_STRING.charAt(rndCharAt);
            sb.append(rndChar);
        }
        return sb.toString();
    }
}